import { assetManager, JsonAsset } from "cc";
import { TbContainer } from "./TbContainer";
import { LogMgr } from "../log/LogMgr";
import { ITbDecode } from "./ITbDecode";



//管理所有表容器
export class TbRoot{

    private static instance:TbRoot = null;
    tbMetas:{
        tbName:string,//表格实体类名
        tbContainerType:new (...args:any[])=>TbContainer<any>,//容器构造函数
        tbContainerName:string//容器类的名字
        tbDecode:new (...args:any[])=>ITbDecode<any>
    }[] = []

    //每个表容器映射{表实体类名:管理所有实体的容器}
    containers:Map<string,TbContainer<any>> = new Map()
    decodes:Map<string,ITbDecode<any>> = new Map()

    //表文件后缀名
    fileSuffix:string = ".json"
    //是否是远程资源
    isRemote:boolean = false
    //CDN地址
    baseUrl:string = null;

    public static get ins(){
        if(!this.instance){
            this.instance = new TbRoot();
        }
        return this.instance;
    }
    public registryContainer(tbEntityName:string,container:new (...args:any)=>TbContainer<any>){
        let found = this.tbMetas.find(meta=>meta.tbName===tbEntityName)
        if(found){
            LogMgr.err(`重复注册容器!表实体名：${tbEntityName}  表容器名：${container.name}`)
            return
        }
        this.tbMetas.push({
            tbName:tbEntityName,
            tbContainerType:container,
            tbContainerName:container.name,
            tbDecode:null
        })
    }

    public registryDecoder(entityName:string,decoder:new (...args:any)=>ITbDecode<any>){
        let found = this.decodes.get(entityName)
        if(found){
            LogMgr.err(`重复注册表格解码器!解码器名：${decoder.name}`)
            return
        }
        this.decodes.set(entityName,new decoder())
    }

    public setTableFileSuffix(suffix:string){

    }
    
    /**
     * 获取单个表的容器
     * @param type 
     * @returns 
     */
    // public getTbContainer<TB, C extends TbContainer<TB>>(type: new (...args: any[]) => C):TbContainer<TB>{
    //     if(!this.containers.has(type.name)){
    //         return null
    //     }
    //     return this.containers.get(type.name)
    // }
    public getTbContainer<C extends TbContainer<any>>(
        type: new (...args: any[]) => C
      ): C{
        if(!this.containers.has(type.name)){
            return null
        }
        return this.containers.get(type.name) as C
      }
    // public getTbContainer<TB,C extends TbContainer<TB>>(type:new (...args:any)=>C):TbContainer<TB>{
    //     if(!this.containers.has(type.name)){
    //         return null
    //     }
    //     return this.containers.get(type.name)
    // }
    public putCfgContainer<T>(name:string,container:TbContainer<T>){
        return this.containers.set(name,container)
    }




    /**
     * 加载配置表
     */
    public async loadTbs(baseUrl:string,isRemote:boolean,fileSuffix:string,onerror?:Function){
        this.tbMetas.forEach(meta=>{
            let {tbName,tbContainerType,tbContainerName} = meta
            let container = new tbContainerType()
            this.containers.set(tbContainerName,container)
            let deocoder = this.decodes.get(tbName)
            if(deocoder){
                container.decoder = deocoder
            }
        })
        //工具导表，工具合并数据，数据文件格式：1byte(写表名长度)+表名的utf-8字节数据，+4byte(数据长度)+数据的字节数据
        //1。一个个加载
        //2。合并加载
        return new Promise((r,j)=>{
            let downladTask = []
            let success = 0
            this.tbMetas.forEach((meta)=>{
                let task = new Promise(async (resolve,reject)=>{
                    let container = this.containers.get(meta.tbContainerName)
                    if(!container.decoder){
                        LogMgr.err("未找到对应的table解码器，数据表名："+meta.tbName)
                        reject("不存在解码器，数据表名："+meta.tbName)
                    }

                    await container.decoder.decode(container)
                    success++;
                    if(success==this.tbMetas.length){
                        resolve(success)
                    }

                    // assetManager.loadRemote("http://127.0.0.1:5500/test.cfg",(e,data)=>{
                    // assetManager.loadRemote(`http://127.0.0.1:5500/${meta.tbName}.json`,(e,data)=>{
                    //     if(e){
                    //         LogMgr.err("加载数据失败：",e)
                    //         reject(e)
                    //         return
                    //     }
                    //     // console.error("加载成功：",data);
                    //     // let cfgBuffer = data.nativeAsset as ArrayBuffer
                    //     // let dv = new DataView(cfgBuffer)
                    //     // let read = dv.getUint32(0)
                    //     // console.log("读取到二进制配置："+read)
                    //     let container = this.containers.get(meta.tbContainerName)
                    //     if(!container.decoder){
                    //         LogMgr.err("未找到对应的table解码器，数据表名："+meta.tbName)
                    //         reject("不存在解码器，数据表名："+meta.tbName)
                    //     }

                    //     container.decoder.decode(container)
                    //     success++;
                    //     if(success==this.tbMetas.length){
                    //         resolve(success)
                    //     }
                    // })
                })
                downladTask.push(task)
            })
            Promise.all(downladTask).then(()=>{
                this.containers.forEach(c=>c.afterDecode())
                r(1)
            }).catch(reason=>{
                onerror?.()
                r(0)
            })
        })

    }
}